package com.mingqijia.gassafety.gateway.controller;

import com.alibaba.fastjson.JSONObject;
import com.gap.basic.base.CommonResponse;
import com.gap.basic.exception.BizException;
import com.mingqijia.gassafety.db.entity.DeviceState;
import com.mingqijia.gassafety.shared.constant.CmpConst;
import com.mingqijia.gassafety.webserver.dto.NotifyDTO;
import com.mingqijia.gassafety.webserver.dto.ReportNotifyDTO;
import com.mingqijia.gassafety.webserver.dto.ReportNotifyOfflineDTO;
import com.mingqijia.gassafety.webserver.request.cmp.notify.DataReportRequest;
import com.mingqijia.gassafety.webserver.request.cmp.notify.RegistrationRequest;
import com.mingqijia.gassafety.webserver.service.cmp.CmpRegistrationService;
import com.mingqijia.gassafety.webserver.service.cmp.impl.CmpAlarmNotifyServiceImpl;
import com.mingqijia.gassafety.webserver.service.cmp.impl.CmpDataNotifyServiceImpl;
import com.mingqijia.gassafety.webserver.service.cmp.impl.CmpRunningNotifyServiceImpl;
import com.mingqijia.gassafety.webserver.service.strategy.RunningStrategyServiceImpl;
import com.mingqijia.gassafety.webserver.service.strategy.StrategyServiceImpl;
import com.mingqijia.gassafety.webserver.service.strategy.WarnStrategyV2ServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.mingqijia.gassafety.webserver.constant.DeviceConstant.WORK_STATUS_1;
import static com.mingqijia.gassafety.webserver.constant.DeviceConstant.WORK_STATUS_2;

/**
 * CMP平台上报数据回调Controller
 *
 * @author zhufeng
 * @since 2022/8/1
 */
@Slf4j
@Api(tags = "CMP平台数据业务通知")
@RestController
@RequestMapping("/iot/alarm")
public class CmpDataNotifyController {

    @Resource
    private CmpDataNotifyServiceImpl notifyServiceImpl;

    @Resource
    private CmpRunningNotifyServiceImpl runningNotifyService;

    @Resource
    private CmpAlarmNotifyServiceImpl alarmNotifyService;

    @Resource
    private CmpRegistrationService cmpRegistrationService;
    @Resource
    private StrategyServiceImpl strategyService;

    @Resource
    private WarnStrategyV2ServiceImpl warnStrategyServiceV2;
    @Resource
    private RunningStrategyServiceImpl runningStrategyService;
    private ExecutorService executor = Executors.newFixedThreadPool(200);

    @ApiOperation("CMP数据上报-通知接收")
    @RequestMapping(value = "/v1/device/data", method = RequestMethod.POST)
    public CommonResponse<Object> dataReportNotify(@RequestBody @Valid DataReportRequest request){
        log.info("数据上报通知接收: {} ", JSONObject.toJSONString(request));
        try {
            request.setRecordType(CmpConst.RECORD_TYPE_2);
            NotifyDTO notifyDTO = notifyServiceImpl.saveReportData( request );
            notifyServiceImpl.notifyState(notifyDTO);

        } catch (BizException ex) {
            log.error("dataReportNotify occur BizException: {}", ex);
            return CommonResponse.failure(ex.getCode(), ex.getMessage());
        } catch (Exception ex) {
            log.error("dataReportNotify occur Exception: {}", ex);
            return CommonResponse.failure(1099, "服务端系统繁忙");
        }
        return CommonResponse.success(null);
    }

    @ApiOperation("CMP运行上报-通知接收")
    @RequestMapping(value = "/v1/device/running", method = RequestMethod.POST)
    public CommonResponse<Object> runningReportNotify(@RequestBody @Valid DataReportRequest request){
        log.info("运行上报通知接收: {} ", JSONObject.toJSONString(request) );
        try {
            request.setRecordType(CmpConst.RECORD_TYPE_3);
            NotifyDTO notifyDTO = runningNotifyService.saveReportData(request);
            runningNotifyService.notifyState(notifyDTO  );
            List<ReportNotifyDTO> reportNotifyDTOList = notifyDTO.getReportNotifyDTOList();
            log.info("runningReportNotify-reportNotifyDTOList: {} ", JSONObject.toJSONString(reportNotifyDTOList));
            if (!CollectionUtils.isEmpty(reportNotifyDTOList)||WORK_STATUS_2.equals(request.getWorkStatus())) {
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        if (WORK_STATUS_2.equals(request.getWorkStatus())||WORK_STATUS_1.equals(request.getWorkStatus())){
                            List<Map<String, Object>> consumerRunningStrategy = runningStrategyService.getConsumerRunningStrategy(
                                    notifyDTO.getSpId(),
                                    notifyDTO.getConsumerId(),
                                    1);
                            if (null!=consumerRunningStrategy && !consumerRunningStrategy.isEmpty()){
                                ReportNotifyOfflineDTO offlineDTO = notifyDTO.getOfflineDTO();
                                runningStrategyService.runningStrategy(offlineDTO.getDtu().getIMEI(),WORK_STATUS_2.equals(request.getWorkStatus())?0:1,1);
                            }
                            return;
                        }
                        if (!CollectionUtils.isEmpty(reportNotifyDTOList)) {
                            List<Map<String, Object>> consumerRunningStrategy = runningStrategyService.getConsumerRunningStrategy(
                                    notifyDTO.getSpId(),
                                    notifyDTO.getConsumerId(),
                                    0);
                            if (null != consumerRunningStrategy && !consumerRunningStrategy.isEmpty()) {
                                reportNotifyDTOList.forEach(req -> {
                                    DeviceState state = req.getPrepareDeviceState();
                                    log.info("strategyService-state: {} ", JSONObject.toJSONString(state));
                                    try {
                                        runningStrategyService.runningStrategy(state.getDeviceId(), WORK_STATUS_2.equals(request.getWorkStatus()) ? 0 : state.getDeviceStatus(), 0);
                                    } catch (Exception e) {
                                        log.error("xxxxx", e);
                                    }
                                });
                            }
                        }
                    }
                });
            }
        } catch (BizException ex) {
            log.error("runningReportNotify occur BizException: {}", ex);
            return CommonResponse.failure(ex.getCode(), ex.getMessage());
        } catch (Exception ex) {
            log.error("runningReportNotify occur Exception: {}", ex);
            return CommonResponse.failure(1099, "服务端系统繁忙");
        }
        return CommonResponse.success(null);
    }

    @ApiOperation("CMP监测上报-通知接收")
    @RequestMapping(value = "/v1/device/monitor", method = RequestMethod.POST)
    public CommonResponse<Object> monitorReportNotify(@RequestBody @Valid DataReportRequest request){
        log.info("监测上报通知接收: {} ", JSONObject.toJSONString(request) );
        try {
            request.setRecordType(CmpConst.RECORD_TYPE_4);
            NotifyDTO notifyDTO = alarmNotifyService.saveReportData(request);
            alarmNotifyService.notifyState( notifyDTO );
            List<ReportNotifyDTO> reportNotifyDTOList = notifyDTO.getReportNotifyDTOList();
            log.info("monitorReportNotify-reportNotifyDTOList: {} ", JSONObject.toJSONString(reportNotifyDTOList) );
            if (!CollectionUtils.isEmpty(reportNotifyDTOList)) {
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        reportNotifyDTOList.forEach(req ->{
                            DeviceState state = req.getPrepareDeviceState();
                            log.info("strategyService-state: {} ", JSONObject.toJSONString(state) );
                            warnStrategyServiceV2.warnStrategy(state.getDeviceId(),state.getDeviceStatus(),state.getConcentration());
                        });
                    }
                });
            }

        } catch (BizException ex) {
            log.error("monitorReportNotify occur BizException: {}", ex);
            return CommonResponse.failure(ex.getCode(), ex.getMessage());
        } catch (Exception ex) {
            log.error("monitorReportNotify occur Exception: {}", ex);
            return CommonResponse.failure(1099, "服务端系统繁忙");
        }
        return CommonResponse.success(null);
    }





    @ApiOperation("CMP激活设备")
    @RequestMapping(value = "/v1/device/registration", method = RequestMethod.POST)
    public CommonResponse<Object> registration(@RequestBody @Valid RegistrationRequest request){
        log.info("CMP激活设备: {} ", request);
        Object res=null;
        try {
            request.setRecordType(CmpConst.RECORD_TYPE_1);
            res= cmpRegistrationService.registration(request);
        } catch (BizException ex) {
            log.error("registration occur BizException: {}", ex);
            return CommonResponse.failure(ex.getCode(), ex.getMessage());
        } catch (Exception ex) {
            log.error("registration occur Exception: {}", ex);
            return CommonResponse.failure(1099, "服务端系统繁忙");
        }
        return CommonResponse.success(res);
    }
}
